import base64
import pickle

from django.shortcuts import render

# Create your views here.



# cart={
#     '1':{
#         'count':5,
#         'selected':True
#     }
# }
#
# import pickle
# import base64
#
# demo = pickle.dumps(cart)
#
# demo1 = base64.b64encode(demo)
#
# demo1.decode()
#
# demo2 = base64.b64decode(demo1)
#
# pickle.loads(demo2)
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

from carts.serializers import CartVIewSerializer
from goods.models import SKU

'''
分为两个方向　用户登陆时的购物车
            １　登陆时的购物车需要前端　用户id　商品id count selected
            ２　接收数据　
            ３　校验数据
            ４　存储到redis中
            ５　哈希表　　set集合
            ６　返回响应
            用户未登录时的购物车
            １　商品的id count selected
            ２　接收数据　如果 判断token  因为django自带的认证系统，我们需要重写
            ３　判断token  token 过期　伪造等
            ４　设置cookies
            ５　加密等

'''
# 请求方式　post cart
from rest_framework.permissions import IsAuthenticated
from django_redis import get_redis_connection

'''
１　添加购物车　用户登陆　与未登录
２　登陆　验证token 商品的id　count selected　　存储在redis中
３　未登录　商品的id count  selected  存储在cookies 中
４　sku_id : {'count':count,'
'''
class CartVIew(APIView):
    # 保持登陆的用户
    # parser_classes = [IsAuthenticated]

    def perform_authentication(self, request):
        '''
        登陆的时候　进行第一站访问　进行验证token
        '''
        pass

    def post(self,request):

        # 接受数据
        data = request.data
        # 校验数据
        serializer = CartVIewSerializer(data=data)
        serializer.is_valid(raise_exception=True)
        # 进行数据的保存
        sku_id = serializer.data
        count = serializer.data
        selected = serializer.data
        try:
            user = request.user
        except Exception:
            user = None

        if user is not None and user.is_authenticated:
            from django_redis import get_redis_connection
            redis_conn = get_redis_connection('cart')
            # hash
            redis_conn.hset('cart_%s'%user.id,sku_id,count)
            # set
            if selected:
                redis_conn.sadd('cart_%s'%user.id,sku_id)

            return Response(serializer.data)

        else:
            cart = request.COOKIES.get('cart')
            if cart is not None:
                # sku_id = cart.get('sku_id')
                # count = cart.get('count')
                # selected= cart.get('selected')
                cart1 = base64.b64decode(cart)
                cart_dict = pickle.loads(cart1)
            else:

                cart_dict = {}
            # 如果商品id　在cook中　就进行数量的相加
            if sku_id in cart_dict.keys():
                orenger_cart = cart_dict[sku_id]['count']

                count += orenger_cart
            # 如果不在的话
            cart_dict[sku_id]={
                    'count':count,
                    'selected':selected
            }
            # 进行加密
            dump = pickle.dumps(cart_dict)
            dumps = base64.b64encode(dump)

            response = Response(serializer.data)
            response.set_cookie('cart',dumps.decode())

            return response

    def get(self,request):
        # 接收数据
        data = request.data
        try:
            user = request.user
        except Exception as e:
            user = None
        # 判断user  有　就从redis 中取数据
        if user is not None and user.is_authenticated:
            redis_conn = get_redis_connection('cart')
            redis_cart = redis_conn.hgetall('cart_%s'%user.id)
            redis_selected = redis_conn.smembers('cart_%s'%user.id)

            cookies_cart = {}
            for sku_id,count in redis_cart:
                if sku_id in redis_selected:
                    flat = True

                else:
                    flat = False

                cookies_cart[int(sku_id)] = {
                    'count':int(count),
                    'selected':flat
                }


        else:
            cookies = request.COOKIES.get('cart')
            if cookies is not None:
                cookies_cart = pickle.loads(base64.b64decode(cookies))

            else:
                cookies_cart = {}
        # 获取所有商品的id
        skus = SKU.objects.filter(id__in=cookies_cart.keys())
        for sku in skus:
            sku.count = cookies_cart[sku.id]['count']
            sku.selected = cookies_cart[sku.id]['selected']

        serializer = CartVIewSerializer(skus,many=True)
        return Response(serializer.data)

    def put(self,request):
        data = request.data

        serializer = CartVIewSerializer(data=data)
        serializer.is_valid(raise_exception=True)

        sku_id = serializer.data.get('sku_id')
        count = serializer.data.get('count')
        selected = serializer.data.get('selected')

        try:
            user = request.user

        except Exception as e:
            user = None

        if user is not None and user.is_authenticated:
            redis_conn = get_redis_connection('cart')
            redis_conn.hset('cart_%s'%user.id,sku_id,count)

            if selected:
                redis_conn.sadd('cart_%s'%user.id,sku_id)

            else:
                redis_conn.srem('cart_%s'%user.id,sku_id)

            return Response(serializer.data)

        else:
            cookies = request.COOKIES.get('cart')

            if cookies is not None:
                cart = pickle.loads(base64.b64decode(cookies))

            else:
                cart = {}

            if sku_id in cart:
                cart[sku_id]={
                    'count':count,
                    'selected':selected
                }

            cookies_encode = base64.b64encode(pickle.dumps(cart))

            response = Response(serializer.data)

            response.set_cookie('cart',cookies_encode.decode())
            return response

    def delete(self,request):

        data = request.data

        serializer = CartVIewSerializer(data=data)
        serializer.is_valid(raise_exception=True)

        sku_id = serializer.data.get('sku_id')

        try:
            user = request.user

        except Exception as e:
            user = None

        if user is not None and user.is_authenticated:

            redis_conn = get_redis_connection('cart')

            redis_conn.hdel('cart_%s'%user.id,sku_id)
            redis_conn.srem('cart_%s'%user.id,sku_id)

            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            cart = request.COOKIES.get('cart')

            if cart is not None:

                cook_cart = pickle.loads(base64.b64decode(cart))
            else:
                cook_cart = {}

            if sku_id in cook_cart:
                del cook_cart[sku_id]

            decode = base64.b64decode(pickle.dumps(cook_cart))

            response = Response(status=status.HTTP_204_NO_CONTENT)

            response.set_cookie('cart',decode.decode())

            return response







